﻿using Avalonia.Controls.Primitives;
using KinonekoSoftware.Foundation.GraphShape.Avalonia.Interfaces;

namespace GraphShape.Controls
{
    /// <summary>
    /// Vertex control.
    /// </summary>
    [PseudoClasses(":highlight", ":semi", ":inedge", "outedge", ":target", ":source")]
    public class VertexControl : TemplatedControl, IPoolObject, IDisposable, IHighlightStateSource
    {
        static VertexControl()
        {
        }

        #region Vertex

        /// <summary>
        /// Vertex object.
        /// </summary>
        public object Vertex
        {
            get => GetValue(VertexProperty);
            set => SetValue(VertexProperty, value);
        }

        /// <summary>
        /// Vertex dependency property.
        /// </summary>
        [NotNull]
        public static readonly StyledProperty<object> VertexProperty = AvaloniaProperty.Register<VertexControl, object>(nameof(Vertex));

        #endregion

        #region RootCanvas

        /// <summary>
        /// Root canvas.
        /// </summary>
        public GraphCanvas RootCanvas
        {
            get => GetValue(RootCanvasProperty);
            set => SetValue(RootCanvasProperty, value);
        }

        /// <summary>
        /// Root canvas dependency property.
        /// </summary>
        [NotNull]
        public static readonly StyledProperty<GraphCanvas> RootCanvasProperty = AvaloniaProperty.Register<VertexControl, GraphCanvas>(nameof(RootCanvas));

        #endregion

        #region IPoolObject

        /// <inheritdoc />
        public void Reset()
        {
            Vertex = null;
        }

        /// <inheritdoc />
        public void Terminate()
        {
            // Nothing to do, there are no unmanaged resources
        }

        /// <inheritdoc />
        public event DisposingHandler Disposing;

        #region IDisposable

        /// <inheritdoc />
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Dispose this object.
        /// </summary>
        /// <param name="disposing">Indicates if called by dispose or finalizer.</param>
        protected virtual void Dispose(bool disposing)
        {
            Disposing?.Invoke(this);
        }

        #endregion

        #endregion
        
        
        public void CheckHighlightState()
        {
            var highlightInfo     = GraphElementBehaviour.GetHighlightInfo(this).ToString();
            var semiHighlightInfo = GraphElementBehaviour.GetSemiHighlightInfo(this).ToString();
            var highlight         = GraphElementBehaviour.GetIsHighlighted(this);
            var semiHighlight     = GraphElementBehaviour.GetIsSemiHighlighted(this);

            
            PseudoClasses.Set("highlight", highlight);
            PseudoClasses.Set("semi", semiHighlight);
            PseudoClasses.Set("target", semiHighlight  && semiHighlightInfo == SemiHighlightInfos.Target);
            PseudoClasses.Set("source", semiHighlight  && semiHighlightInfo == SemiHighlightInfos.Source);
            PseudoClasses.Set("inedge", semiHighlight  && semiHighlightInfo == SemiHighlightInfos.InEdge);
            PseudoClasses.Set("outedge", semiHighlight && semiHighlightInfo == SemiHighlightInfos.OutEdge);
            
        }
    }
}